home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dirut / new17.zip / NEW.C < prev    next >
C/C++ Source or Header  |  1989-02-17  |  17KB  |  617 lines

  1. /* NEW.C (V1.7) -- Written by Scott R. Houck   17 Feb 89
  2.  *
  3.  * Directory listing of files since or before a certain number of days.
  4.  *
  5.  * Modelled after Jay Jervey's utility.  My version lists the file
  6.  * information in the standard DOS directory listing format (except that
  7.  * I am also showing the seconds in the file time), adds some features
  8.  * (/p, /s and /e), and corrects some errors in Jervey's utility.  Julian
  9.  * date calculations were adapted from James Seed's c_dates library.
  10.  *
  11.  * Compiled with MSC version 5.1.  Uses PforCe functions drfullpath() and
  12.  * vidcsrtyp().
  13.  *
  14.  * The syntax is:  NEW [filespec [filespec...]] [options]
  15.  *
  16.  * Options and filespec can be in any order.  Valid options are:
  17.  *
  18.  *      /h     Show help screen
  19.  *      /?     Same as /h
  20.  *      /n     Show files SINCE the number of days specified by n
  21.  *      /-n    Show files BEFORE the number of days specified by n
  22.  *      /p     Pause when screen display is full
  23.  *      /s     Search specified directory and its subdirectories
  24.  *      /e     Search entire disk
  25.  *      /d     Include directories in listing
  26.  *      /do    Include directories ONLY in listing
  27.  *      /j     Junk option -- include files with corrupted dates
  28.  *      /i     Ignore the environment variable NEW if it is defined
  29.  *
  30.  * If filespec is omitted, *.* is assumed.  Also, a "day" in this program
  31.  * starts at 6:00 am and ends at 5:59 am the following day.
  32.  *
  33.  * Compile with:   cl -AL new.c pfms3l.lib /link /st:40000 /e
  34.  *
  35.  * Version 1.3 handles file dates where year > 99 (corrupted filestamps).
  36.  * Version 1.4 will not display files whose date and time are greater than
  37.  *   the current date and time unless the /J (junk) option is chosen.
  38.  *   Also added /D to include directories in listing.
  39.  * Version 1.5 checks the number of text rows available so that the pause
  40.  *   option (/P) pauses at the correct place.
  41.  * Version 1.6 allows multiple filespecs and is handy for specifying
  42.  *   multiple drives to be searched with the /e option.  For example,
  43.  *   NEW c: d: /e.
  44.  * Version 1.7 checks for an environment variable named NEW to find
  45.  *   default options and/or filespecs.  If it is defined, but you want
  46.  *   NEW to ignore the environment variable, you may specify /I (for
  47.  *   Ignore) on the command line.  Request for NEW environment variable
  48.  *   came from Richard Hallowell.  Also added /DO option to include
  49.  *   directories ONLY in the listing (no regular files are included).
  50.  */
  51.  
  52. #include <stdio.h>
  53. #include <string.h>
  54. #include <stdlib.h>
  55. #include <conio.h>
  56. #include <ctype.h>
  57. #include <dos.h>
  58. #include <io.h>
  59. #include "pdefs.h"
  60.  
  61. struct packed_date {
  62.    unsigned da : 5;
  63.    unsigned mo : 4;
  64.    unsigned yr : 7;
  65. };
  66.  
  67. struct packed_time {
  68.    unsigned ss : 5;
  69.    unsigned mm : 6;
  70.    unsigned hh : 5;
  71. };
  72.  
  73. #define PACKED_DATE(d) (*(struct packed_date *)(&(d)))
  74. #define PACKED_TIME(t) (*(struct packed_time *)(&(t)))
  75.  
  76. typedef struct node   NODE, *NODEPTR;
  77.  
  78. struct node {
  79.    struct find_t   finfo;
  80.    char            path[80];
  81.    NODEPTR         next;
  82. };
  83.  
  84. /* "modes" for parse() function */
  85.  
  86. #define CMDLINE 0
  87. #define ENVIRON 1
  88.  
  89. char *syntax[] = {
  90.    "The syntax is:  NEW [filespec [filespec...]] [options]\n",
  91.    "Options and filespec can be in any order.  Valid options are:\n",
  92.    "    /h     Show this help screen",
  93.    "    /?     Same as /h",
  94.    "    /n     Show files SINCE the number of days specified by n",
  95.    "    /-n    Show files BEFORE the number of days specified by n",
  96.    "    /p     Pause when screen display is full",
  97.    "    /s     Search specified directory and its subdirectories",
  98.    "    /e     Search entire disk",
  99.    "    /d     Include directories in listing",
  100.    "    /do    Include directories ONLY in listing",
  101.    "    /j     Junk option -- include files with corrupted dates",
  102.    "    /i     Ignore the environment variable NEW if it is defined\n",
  103.    "If filespec is omitted, *.* is assumed.  Also, a \"day\" in this "
  104.       "program",
  105.    "starts at 6:00 am and ends at 5:59 am the following day.", 0
  106. };
  107.  
  108. char *cdow[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
  109.    "Friday", "Saturday" };
  110.  
  111.  
  112. /* global variables */
  113.  
  114. int before   = NO;
  115. int pausing  = NO;
  116. int entire   = NO;
  117. int subdirs  = NO;
  118. int junk     = NO;
  119. int dirs     = NO;
  120. int ignore   = NO;
  121. int dirsonly = NO;
  122. size_t hits  = 0;
  123. int lines    = 3;
  124. long since   = 1L;
  125. long jul, tjul;      /* jul = date to check for, tjul = today's date */
  126. NODEPTR filehead = NULL;
  127. NODEPTR filetail = NULL;
  128. NODEPTR spechead = NULL;
  129. NODEPTR spectail = NULL;
  130. NODEPTR *larray;
  131. char hitfile[256];
  132. char findspec[256];
  133. int numrows;         /* number of text rows */
  134.  
  135.  
  136. /* function prototypes */
  137.  
  138. void parse(char *, int, int);
  139. void print_syntax(void);
  140. long gtoj(int, int, int);
  141. void jtog(long, int *, int *, int *);
  142. int dow(long);
  143. NODEPTR addlist(struct find_t, char *, NODEPTR *, NODEPTR *);
  144. int compare();
  145. void display(void);
  146. void check_pause(void);
  147. void search(char *, char *);
  148.  
  149.  
  150. main(int argc, char **argv)
  151. {
  152.    int month, day, year, hours, i, option, len;
  153.    char *ptr, *p, *q, fullpath[128], basepath[128], filespec[13];
  154.    char environ[128], envarg[128];
  155.    struct dosdate_t date;
  156.    struct dostime_t time;
  157.    NODEPTR n;
  158.    struct find_t dummy;
  159.  
  160.    /* Determine the number of text rows by looking at 0040:0084h */
  161.    numrows = (int)(*(char far *)0x00400084);
  162.    if (numrows == 0)
  163.       numrows = 24;
  164.  
  165.    /* Could also have used INT 10h, function 1130h, which returns the
  166.     * number of rows (minus 1) in DL
  167.     */
  168.  
  169.    fprintf(stderr, "NEW V1.7 by Scott R. Houck\n");
  170.  
  171.    while (--argc)
  172.       {
  173.       option = (**++argv == '/');
  174.       ptr = strtok(*argv, "/");
  175.       parse(ptr, option, CMDLINE);
  176.       while (ptr = strtok(NULL, "/"))
  177.          parse(ptr, 1, CMDLINE);
  178.       }
  179.  
  180.    /* Check the environment for NEW options/filespecs */
  181.    if (!ignore && (p = getenv("NEW")) != NULL)
  182.       {
  183.       strcpy(environ, p);
  184.       p = environ;
  185.       while (*p)
  186.          {
  187.          /* strip off whitespace */
  188.          while (isspace(*p))
  189.             p++;
  190.          /* scan for whitespace */
  191.          for (q = p; *q && !isspace(*q); q++)
  192.             ;
  193.          if (*q)
  194.             {
  195.             strncpy(envarg, p, q-p);
  196.             *q = EOS;
  197.             p = q + 1;
  198.             }
  199.          else
  200.             {
  201.             strcpy(envarg, p);
  202.             p = q;
  203.             }
  204.          option = (*envarg == '/');
  205.          ptr = strtok(envarg, "/");
  206.          parse(ptr, option, ENVIRON);
  207.          while (ptr = strtok(NULL, "/"))
  208.             parse(ptr, 1, ENVIRON);
  209.          }
  210.       }
  211.  
  212.    if (!spechead)
  213.       addlist(dummy, "*.*", &spechead, &spectail);
  214.  
  215.    _dos_getdate(&date);
  216.    _dos_gettime(&time);
  217.    if (time.hour >= 6)
  218.       --since;
  219.    tjul = gtoj(date.month, date.day, date.year);
  220.    jul = tjul - since;
  221.    jtog(jul, &month, &day, &year);
  222.  
  223.    printf("Directory %s 6 am %s, %d-%02d-%02d\n\n",
  224.       before ? "before" : "since",
  225.       cdow[dow(jul)], month, day, year % 100);
  226.  
  227.    if (subdirs || entire)
  228.       if (!isatty(fileno(stdout)))
  229.          fprintf(stderr, "\n");
  230.  
  231.    for (n = spechead; n; n = n->next)
  232.       {
  233.       strupr(strcpy(filespec, n->path));
  234.       drfullpath(fullpath, 0, filespec);     /* PforCe */
  235.  
  236.       if (strchr(fullpath, '*') == NULL && strchr(fullpath, '?') == NULL)
  237.          {
  238.          if (fullpath[strlen(fullpath)-1] == '\\')
  239.             strcat(fullpath, "*.*");
  240.          else
  241.             strcat(fullpath, "\\*.*");
  242.          }
  243.  
  244.       p = strrchr(fullpath, '\\');
  245.       len = p - fullpath + 1;
  246.       strncpy(basepath, fullpath, len);
  247.       basepath[len] = EOS;
  248.       strcpy(filespec, p+1);
  249.  
  250.       if (entire)
  251.          {
  252.          subdirs = YES;
  253.          basepath[3] = EOS;
  254.          fullpath[2] = EOS;
  255.          strcat(fullpath, filespec);
  256.          }
  257.  
  258.       if (subdirs)
  259.          vidcsrtyp(CSR_HIDDEN);  /* PforCe */
  260.  
  261.       search(basepath, filespec);
  262.  
  263.       if (subdirs)
  264.          {
  265.          fprintf(stderr, "%-79s\r", "");
  266.          vidcsrtyp(CSR_NORMAL);  /* P